#include "camusb.h"
#include <android/log.h>
#include <sys/ioctl.h>
#include <linux/usbdevice_fs.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>  

#define  LOG_TAG    "camusb_c"
#define  LOGI(...)  //__android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
#define  LOGE(...)  __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)

static cam_cb camUsbStatusChangedCb    = NULL;
static int camUsbNativefd = 0;
static int camUsbInited = 0;

#define USB_CAM_WRITECMD_EP	0x01
#define USB_CAM_READCMD_EP	0x82
#define USB_CAM_WRITETS_EP	0x03
#define USB_CAM_READTS_EP	0x84

int CamUsbReadTsData(unsigned char *ts_buffer, int *data_len, int timeout)
{
	int ret;
	struct usbdevfs_bulktransfer  ctrl;

	//LOGE("CamUsbReadTsData Start !!" );
	if(camUsbNativefd > 0)
	{
		if(*data_len > 16384)
		{
			*data_len = 16384;
		}
		memset(&ctrl, 0, sizeof(ctrl));
		ctrl.ep = USB_CAM_READTS_EP;
		ctrl.len = *data_len;
		ctrl.data = ts_buffer;
		ctrl.timeout = timeout;
		ret = ioctl(camUsbNativefd, USBDEVFS_BULK, &ctrl);
		if(ret < 0)
		{
			LOGE("CamUsbReadTsData ioctl error!%s\r\n", strerror(errno));
			ret = -1;
		}
		else
		{
			//LOGE("CamUsbReadTsData ioctl ok!ret = %d\r\n", ret );
			*data_len = ret;
		}
	}
	else
	{
		LOGE("CamUsbReadTsData camUsbNativefd = %d < 0\r\n", camUsbNativefd );
		ret = -1;
	}
	//LOGE("CamUsbReadTsData end !!" );

	return ret;
}

int CamUsbWriteTsData(unsigned char *ts_buffer, int *data_len, int timeout)
{
	int ret;
	struct usbdevfs_bulktransfer  ctrl;

	//LOGE("CamUsbReadTsData Start !!" );
	if(camUsbNativefd > 0)
	{
		if(*data_len > 16384)
		{
			*data_len = 16384;
		}
		memset(&ctrl, 0, sizeof(ctrl));
		ctrl.ep = USB_CAM_WRITETS_EP;
		ctrl.len = *data_len;
		ctrl.data = ts_buffer;
		ctrl.timeout = timeout;
		ret = ioctl(camUsbNativefd, USBDEVFS_BULK, &ctrl);
		if(ret < 0)
		{
			LOGE("CamUsbWriteTsData ioctl error!%s\r\n", strerror(errno));
			ret = -1;
		}
		else
		{
			//LOGE("CamUsbReadTsData ioctl ok!ret = %d\r\n", ret );
			*data_len = ret;
		}
	}
	else
	{
		LOGE("CamUsbWriteTsData camUsbNativefd = %d < 0\r\n", camUsbNativefd );
		ret = -1;
	}
	//LOGE("CamUsbReadTsData end !!" );

	return ret;
}

int CamUsbReadCmd (unsigned char *cmd_buffer, int *data_len, int timeout)
{
	int ret;
	struct usbdevfs_bulktransfer  ctrl;

	//LOGE("CamUsbReadTsData Start !!" );
	if(camUsbNativefd > 0)
	{
		if(*data_len > 16384)
		{
			*data_len = 16384;
		}
		memset(&ctrl, 0, sizeof(ctrl));
		ctrl.ep = USB_CAM_READCMD_EP;
		ctrl.len = *data_len;
		ctrl.data = cmd_buffer;
		ctrl.timeout = timeout;
		ret = ioctl(camUsbNativefd, USBDEVFS_BULK, &ctrl);
		if(ret < 0)
		{
			LOGE("CamUsbReadCmd ioctl error!%s\r\n", strerror(errno));
			ret = -1;
		}
		else
		{
			//LOGE("CamUsbReadTsData ioctl ok!ret = %d\r\n", ret );
			*data_len = ret;
		}
	}
	else
	{
		LOGE("CamUsbReadCmd camUsbNativefd = %d < 0\r\n", camUsbNativefd );
		ret = -1;
	}
	//LOGE("CamUsbReadTsData end !!" );

	return ret;
}

int CamUsbWriteCmd (unsigned char *cmd_buffer, int data_len, int timeout)
{
	int ret;
	struct usbdevfs_bulktransfer  ctrl;

	//LOGE("CamUsbReadTsData Start !!" );
	if(camUsbNativefd > 0)
	{
		if(data_len > 16384)
		{
			data_len = 16384;
		}
		memset(&ctrl, 0, sizeof(ctrl));
		ctrl.ep = USB_CAM_WRITECMD_EP;
		ctrl.len = data_len;
		ctrl.data = cmd_buffer;
		ctrl.timeout = timeout;
		ret = ioctl(camUsbNativefd, USBDEVFS_BULK, &ctrl);
		if(ret < 0)
		{
			LOGE("CamUsbWriteCmd ioctl error!%s\r\n", strerror(errno));
			ret = -1;
		}
		else
		{
			//LOGE("CamUsbWriteCmd ioctl ok!ret = %d\r\n", ret );
			data_len = ret;
		}
	}
	else
	{
		LOGE("CamUsbReadCmd camUsbNativefd = %d < 0\r\n", camUsbNativefd );
		ret = -1;
	}
	//LOGE("CamUsbReadTsData end !!" );
	return ret;
}

int CamUsbHotReset ()
{
	int ret;
	struct usbdevfs_ctrltransfer ctrl;

	LOGI("CamUsbHotReset() - entry!" );
	if(camUsbNativefd > 0)
	{
		ctrl.bRequestType = 0x40;
		ctrl.bRequest = 0xA0;
		ctrl.wValue = 0;
		ctrl.wIndex = 0;
		ctrl.data = NULL;
		ctrl.wLength = 0;
		ctrl.timeout = 100;
		ret = ioctl(camUsbNativefd, USBDEVFS_CONTROL, &ctrl);
		if(ret < 0)
		{
			LOGE("CamUsbHotReset() - ioctrl error!%s\r\n", strerror(errno));
		}
	}
	LOGI("CamUsbHotReset() - return! ret = %d\r\n", ret);
	return ret;
}

int CamUsbHotReplug ()
{
	int ret;

	LOGI("CamUsbHotReplug() - entry!" );
	if(camUsbNativefd > 0)
	{
		ret = ioctl(camUsbNativefd, USBDEVFS_RESET, NULL);
		if(ret < 0)
		{
			LOGE("CamUsbHotReplug() - ioctrl error!%s\r\n", strerror(errno));
		}
	}
	LOGI("CamUsbHotReplug() - return! ret = %d\r\n", ret);
	return ret;
}

void CamUsbStatusChanged(cam_cb pcam_cb){
	
	LOGI("Register cam_cb in CamUsbStatusChanged!\n" );
	camUsbStatusChangedCb = pcam_cb;
	
}

int CamUsbStatusChangedNotify(unsigned char u8Status, int s32Fd) 
{

	LOGI("CamUsbStatusChanged() - entry !\n" );
	if(camUsbStatusChangedCb != NULL){
		camUsbStatusChangedCb((unsigned char)u8Status);
	} else {
		LOGE("camUsbStatusChangedCb is NULL !!\n" );
	}
	
	if(u8Status == 1)
		camUsbNativefd = s32Fd;
	else
		camUsbNativefd = 0;
}

